/**
 * 
 */
package dt.inlee.common.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import dt.inlee.system.vo.TreeNodeBean;

/**
 * @功能说明：树形结构处理工具类
 * @作者： 印鲜刚
 * @创建日期： 2010-5-15
 * @
 */
public class TreeUtil {
	@SuppressWarnings("unused")
    private static Logger logger = Logger.getLogger(TreeUtil.class);

	/**
	 * 将domain对象类型的List树节点进行排序整理转换成VO[MenuTreeNode]对象返回
	 * @param root 
	 * @param entityTreeList
	 * @return treeNodeBean
	 */
	public static TreeNodeBean convertMenuTreeNode(Object root, List<?> entityTreeList) throws Exception {

		TreeNodeBean treeNodeBean = new TreeNodeBean();
		List<TreeNodeBean> menuTreeNodes = new ArrayList<TreeNodeBean>();
		for (Object entity : entityTreeList) {
			menuTreeNodes.add(entityConvertTreeNodeBean(entity));
		}
		TreeNodeBean rootNode = entityConvertTreeNodeBean(BaseUtil.isEmpty(root) ? getRootNode(entityTreeList) : root);
		if (!BaseUtil.isEmpty(root) && rootNode.getAttr().get("rel").equals("")) {
			rootNode.getAttr().put("rel", "root");
		}
		treeNodeBean = getSubNode(menuTreeNodes, rootNode);
		return treeNodeBean;
	}

	/**
	 * 将domain对象类型的List树节点进行排序整理转换成VO[MenuTreeNode]对象返回
	 * @param entityTreeList
	 * @return treeNodeBean
	 */
	public static TreeNodeBean convertMenuTreeNode(List<?> entityTreeList) throws Exception {
		return convertMenuTreeNode(null, entityTreeList);
	}

	/**
	 * 获取所有节点的根节点
	 * 
	 * @param entityTreeList
	 * @return
	 */
	private static Object getRootNode(List<?> entityTreeList) throws Exception {
		for (Object entity : entityTreeList) {
			Method getParentIdMethod = entity.getClass().getMethod("getParentId", new Class[] {});
			String parentId = (String) getParentIdMethod.invoke(entity, new Object[] {});
			if (BaseUtil.isEmpty(parentId))
				return entity;
		}
		return null;
	}

	/**
	 * 根据根节点获取直接和间接子节点[迭代方法实现]
	 * @param list
	 *            所有树节点
	 * @param parent
	 *            根节点
	 * @return
	 */
	private static TreeNodeBean getSubNode(final List<TreeNodeBean> list, TreeNodeBean parent) {
		TreeNodeBean treeNodeBean = new TreeNodeBean();
		List<TreeNodeBean> templist = new ArrayList<TreeNodeBean>();
		// 查找满足条件的的节点,并加入临时集合中
		for (TreeNodeBean treebean : list) {
			if (treebean.getAttr().get("parentId").equals(parent.getAttr().get("id"))) {
				templist.add(treebean);
			}
		}
		if (templist.size() != 0) {
			// 查询完毕排序
			templist = orderNoSort(templist);
		}

		List<TreeNodeBean> children = new ArrayList<TreeNodeBean>();
		for (TreeNodeBean temptreebean : templist) {
			// 递归调用获取子节点
			TreeNodeBean tempTreebean = getSubNode(list, temptreebean);
			children.add(tempTreebean);
		}
		treeNodeBean.setChildren(children);
		treeNodeBean.setData(parent.getData());
		treeNodeBean.setAttr(parent.getAttr());
		return treeNodeBean;
	}

	/**
	 * 排序功能
	 * 
	 * @param list
	 */
	private static List<TreeNodeBean> orderNoSort(List<TreeNodeBean> list) {

		Collections.sort(list, new Comparator<TreeNodeBean>() {
			public int compare(TreeNodeBean treeNodeBean0, TreeNodeBean treeNodeBean1) {
				Integer oldOrderNo = Integer.parseInt(treeNodeBean0.getAttr().get("orderNo"));
				Integer newOrderNo = Integer.parseInt(treeNodeBean1.getAttr().get("orderNo"));
				return oldOrderNo.compareTo(newOrderNo);
			}
		});
		return list;
	}

	/**
	 * 类型转换[实体转换成树节点TreeNodeBean对象]
	 * 
	 * @param entityNode
	 * @return
	 * @throws Exception
	 */
	private static TreeNodeBean entityConvertTreeNodeBean(Object entityNode) throws Exception {
		Method getNameMethod = entityNode.getClass().getMethod("getName", new Class[] {});
		String name = (String) getNameMethod.invoke(entityNode, new Object[] {});
		Method getIdMethod = entityNode.getClass().getMethod("getId", new Class[] {});
		String id = (String) getIdMethod.invoke(entityNode, new Object[] {});
		Method getOrderNoMethod = entityNode.getClass().getMethod("getOrderNo", new Class[] {});
		Integer orderNo = (Integer) getOrderNoMethod.invoke(entityNode, new Object[] {});
		Method getParentIdMethod = entityNode.getClass().getMethod("getParentId", new Class[] {});
		String parentId = (String) getParentIdMethod.invoke(entityNode, new Object[] {});
		Method getRemarkMethod = entityNode.getClass().getMethod("getRemark", new Class[] {});
		String remark = (String) getRemarkMethod.invoke(entityNode, new Object[] {});
		TreeNodeBean treeNodeBean = new TreeNodeBean();
		treeNodeBean.setData(name);
		Map<String, String> map = new HashMap<String, String>();
		map.put("id", id);
		map.put("parentId", BaseUtil.isEmpty(parentId) ? "" : parentId);
		map.put("orderNo", BaseUtil.isEmpty(orderNo) ? "" : String.valueOf(orderNo));
		map.put("remark", BaseUtil.isEmpty(remark) ? "" : remark);
		try {
			Method getNodeImage = entityNode.getClass().getMethod("getNodeImage", new Class[] {});
			String nodeImage = (String) getNodeImage.invoke(entityNode, new Object[] {});
			if (BaseUtil.isEmpty(nodeImage))
				map.put("rel", "");
			else {
				if (nodeImage.indexOf(".") > -1)
					map.put("rel", nodeImage.substring(0, nodeImage.indexOf(".")));
				else
					map.put("rel", nodeImage);
			}
		} catch (Exception e) {
			map.put("rel", "");
		}
		try {
			Method getFlagMethod = entityNode.getClass().getMethod("getFlag", new Class[] {});
			String flag = (String) getFlagMethod.invoke(entityNode, new Object[] {});
			map.put("flag", flag);
		} catch (Exception e) {
			map.put("flag", "");
		}

		try {
			Method getFlagMethod = entityNode.getClass().getMethod("getInternalCommand", new Class[] {});
			String internalCommand = (String) getFlagMethod.invoke(entityNode, new Object[] {});
			map.put("internalCommand", internalCommand);
		} catch (Exception e) {
			map.put("internalCommand", "");
		}

		try {
			Method getPageUrlMethod = entityNode.getClass().getMethod("getPageUrl", new Class[] {});
			String pageUrl = (String) getPageUrlMethod.invoke(entityNode, new Object[] {});
			map.put("pageUrl", BaseUtil.isEmpty(pageUrl) ? "" : pageUrl);
		} catch (Exception e) {
			map.put("pageUrl", "");
		}
		try {
			Method getShortNameMethod = entityNode.getClass().getMethod("getShortName", new Class[] {});
			String shortName = (String) getShortNameMethod.invoke(entityNode, new Object[] {});
			map.put("shortName", BaseUtil.isEmpty(shortName) ? "" : shortName);
		} catch (Exception e) {
			map.put("shortName", "");
		}
		try {
			Method getOrganizationNumberMethod = entityNode.getClass().getMethod("getOrganizationNumber",
					new Class[] {});
			String organizationNumber = (String) getOrganizationNumberMethod.invoke(entityNode, new Object[] {});
			map.put("organizationNumber", BaseUtil.isEmpty(organizationNumber) ? "" : organizationNumber);
		} catch (Exception e) {
			map.put("organizationNumber", "");
		}
		map.put("name", name);
		treeNodeBean.setAttr(map);
		return treeNodeBean;
	}
}
